import os
import sys
from optparse import OptionParser
import logging
import glob
import shutil

from django.conf import settings
from django.db import connection

from browsertests.utils import cli_wrapper
from browsertests.results.models import Result

log = logging.getLogger(__name__)

def db_consistency_check(dummy):
    cursor = connection.cursor()
    #cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz])
    cursor.execute("SELECT r.id FROM results_result r "
        "LEFT OUTER JOIN useragents_useragent u ON ( r.ua_id = u.id )"
        "WHERE u.id IS NULL"
    )

    result_ids = (r[0] for r in cursor.fetchall())
    for result_id in result_ids:
        log.info("Found result id with no matching ua: %s", result_id)
        result = Result.objects.get(pk=result_id)
        #log.debug("result %s", result)
        if not dummy:
            log.info("deleting...")
            result.delete()

def remove_orphan_reftests(reftest_results_path, dummy):
    existing_paths = set()
    for fullpath in glob.glob(os.path.join(reftest_results_path, "*", "*")):
        lastpaths = fullpath.split(os.sep)[-2:]
        existing_paths.add("/".join(lastpaths))

    db_paths = set(f["saved_path"] for f in Result.objects.exclude(saved_path="").values("saved_path"))

    orphan_tests = db_paths - existing_paths
    if orphan_tests:
        log.warn("%s tests with no reftest_results file detected.",
                 len(orphan_tests))

    orphan_paths = existing_paths - db_paths
    for path in orphan_paths:
        path = os.path.join(reftest_results_path, path)
        log.debug("Deleting %s", path)
        if dummy:
            log.debug("Dummy mode, skipping delete")
        else:
            shutil.rmtree(path)

    for path in glob.glob(os.path.join(reftest_results_path, "*")):
        log.debug("Maybe removing empty directory %s", path)
        if not dummy:
            try:
                os.path.rmdir(path)
            except:
                pass

    log.info("Of the %s existing paths, %s were orphan",
             len(existing_paths), len(orphan_paths))


def main():
    usage = ("%prog [OPTIONS] COMMAND\n\n"
             " COMMAND can be:\n"
             "  db-consistency-check: Check database consistency and repair "
                "(if no --dummy option is given).\n"
             "  remove-orphan-reftests: Deletes orphan reftest images.\n")

    parser = OptionParser(usage=usage)
    parser.add_option('--reftest-results-path',
        help='Path of the reftest images')

    parser = cli_wrapper.add_common_parser_options(parser)
    options, args = parser.parse_args()

    if len(args) != 1:
        parser.print_help()
        sys.exit(2)

    cli_wrapper.process_options(options)
    command = args[0]

    if command == "db-consistency-check":
        db_consistency_check(options.dummy)
    elif command == "remove-orphan-reftests":
        reftest_results_path = None

        if hasattr(settings, "REFTEST_RESULTS_PATH"):
            reftest_results_path = settings.REFTEST_RESULTS_PATH
        if options.reftest_results_path:
            reftest_results_path = options.reftest_results_path
        if not reftest_results_path:
            print("Missing path to reftests (--reftest-results-path option or "
                  "REFTEST_RESULTS_PATH setting)")
            sys.exit(2)
        remove_orphan_reftests(reftest_results_path, options.dummy)
    else:
        print "Unknown command: %s\n" % command
        parser.print_help()
        sys.exit(2)
